//
// file : xmlparser.h
// date : 12/04/04
//
#ifndef XMLPARSER_H_
#define XMLPARSER_H_

typedef unsigned char  xmlc_t;
typedef unsigned long  xmln_t;

typedef struct trio_t 
{
#define TRIO_CLOSED (1)
    xmln_t   flg; // flags
    xmln_t   idx; // index for 'tag'
    xmlc_t  *tag;
    xmlc_t  *val;

}  trio_t;

#define GOOD_TRIO(t)  ((t)->idx||(t)->tag)

//
// represent a path in xml parsing tree
//
typedef struct path_t
{
    xmln_t   pnt;   // index to cuurent item in 'trio[]'

    // in practice, the depth a schema uses is limited
    // we make it a predefined value here

#define XML_MAX_DEPTH  (32)

    xmln_t   dep;   // depth

    trio_t  trio[XML_MAX_DEPTH];  // tag-val pairs

}  path_t;

//
// parser context
//
typedef struct xmlpc_t 
{
    path_t  *path;

    xmln_t   msg_pnt;

    xmln_t   msg_len;

#define XMLBUF_LEN  (4096)

    xmlc_t   msg_buf[XMLBUF_LEN];

}  xmlpc_t;

//
// parser input/output
//
typedef struct xmlio_t
{
    void    *app;  // application context

    long    msg_id;

    xmlc_t  (*get_xmlc)(void);    // get a character input

    // entring a new node
    long    (*xml_node)(struct xmlio_t *in); 

    // closing a node, a branch of parsing tree
    long    (*xml_path)(struct xmlio_t *in); 

    // end of xml message
    long    (*xml_end)(struct xmlio_t *in); 

    xmlc_t  *fin;  // a tag terminating an xml message

    xmlpc_t *ctx;   // parser context

}  xmlio_t;


/////////////////////////////////////////////////////////////////////////////


#define CR             (int)(0x0d)

#define LF             (int)(0x0a)

#define Z_TO_LOWER(c)  ((((c)>='A')&&((c)<='Z'))?('a'+c-'A'):(c))

#define Z_IS_WHITE(c)  ((c)==' '||(c)=='\t')

/* white space can be null, to accommandate string's end */
#define Z_IS_WHITE_NULL(c)  ((c)=='\0'||(c)==' '||(c)=='\t')

/////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif

int     xml_prefix(xmlc_t *prefix, xmlc_t *str);
int     xml_caseprefix(xmlc_t *prefix, xmlc_t *str);
int     xml_match(xmlc_t *to, xmlc_t *fr);
xmlc_t* xml_dup(xmlc_t *str);

xmlpc_t*  xmlpc_init(void);
void    xmlpc_reset(xmlpc_t *pc);
void    xmlpc_free(xmlpc_t *pc);
long    xml_feed(xmlc_t c, xmlio_t *in);
long    xml_proc(xmlio_t *in);
#ifdef __cplusplus
}
#endif


#endif // XMLPARSER_H_
//
